<template>
  <div class="ui-timerangs">
    <ui-table-select-item
      v-model="type"
      @change="changeHandle"
      :label="label"
      name="_searchTimeType"
      type="radio"
      ui="button"
      :data="searchTimeTypes"
      :init-default="false"
      :default-value="this.realDefaultType"
      ignore
    />
    <ui-table-select-item
      v-show="isCustom"
      v-model="customType"
      name="_custom"
      type="radio"
      ui="button"
      :data="customTypes"
      :default-value="defaultCustomType"
      ignore
    />
    <template v-if="!refreshing">
      <ui-table-select-item
        v-if="onRealTime"
        name="_time"
        value-format="yyyy-MM-dd HH:mm:ss"
        ignore
        shortcuts=""
        :clearable="clearable"
        :show-label="false"
        :type="pickerType"
        :default-value="latestTime"
        :default-time="pickerDefaultTime"
        :picker-options="pickerOptions"
        @change="onChange"
        @blur="onBlur"
      />
    </template>
    <ui-table-select-item
      type="hidden"
      name="searchTimeType"
      select="eq"
      :value="searchTimeType"
      :default-value="searchTimeType"
    />
    <ui-table-select-item
      type="hidden"
      :name="defaultName"
      :select="datePickerSelect"
      :range="rangeCfg"
      :rangeNames="rangeNames"
      :value="latestTimeValue"
      :default-value="latestTimeValue"
    />
  </div>
</template>

<script>
import moment from "moment";

const TimeTypes = {
  min: { key: "min", label: "分钟", value: "101", picker: "min" },
  time: { key: "time", label: "小时", value: "102", picker: "time" },
  date: { key: "date", label: "日", value: "103", picker: "date" },
  month: { key: "month", label: "月", value: "105", picker: "month" },
  year: { key: "year", label: "年", value: "107", picker: "year" },
  custom: { key: "custom", label: "自定义", value: "custom", picker: "custom" },
  realTime: {
    key: "realTime",
    label: "实时",
    value: "realTime",
    picker: "realTime",
  },
};

export default {
  name: "ui-timerangs",
  props: {
    label: {
      type: String,
      default: "选择日期",
    },
    defaultName: {
      type: String,
      default: "latestTime",
    },
    range: {
      type: Boolean,
      default: false,
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    rangeCfg: null,
    rangeNames: null,
    types: {
      type: String,
      default: "date,month,year",
    },
    searchTypes: Array,
    defaultType: null,
    defaultTime: String,
    defaultCustomType: null,
    getDefaultTime: Function,
    getPickerOptions: Function,
  },
  data() {
    return {
      latestTime: this.defaultTime,
      type: this.getRealDefaultType(
        this.getSearchTimeTypes(),
        this.defaultType
      ),
      refreshing: false,
      customType: this.defaultCustomType || "102",
      onRealTime: true,
      customTypes: [
        { label: "时", value: "102" },
        { label: "日", value: "103" },
      ],
    };
  },
  computed: {
    latestTimeValue({ latestTime, range, picker }) {
      if (range && picker === "month") {
        if (!latestTime) {
          return "";
        }
        const [start, end] = latestTime.split(",");
        const startDate = moment(start, "YYYY-MM-DD HH:mm:ss");
        const endDate = moment(end, "YYYY-MM-DD HH:mm:ss");
        if (!startDate.isValid() || !endDate.isValid()) {
          return "";
        }
        return [
          startDate.startOf("month").format("YYYY-MM-DD HH:mm:ss"),
          endDate.endOf("month").format("YYYY-MM-DD HH:mm:ss"),
        ].join(",");
      }
      if (range && picker === "year") {
        if (!latestTime) {
          return "";
        }
        const [start, end] = latestTime.split(",");
        const startDate = moment(start, "YYYY-MM-DD HH:mm:ss");
        const endDate = moment(end, "YYYY-MM-DD HH:mm:ss");
        if (!startDate.isValid() || !endDate.isValid()) {
          return "";
        }
        return [
          startDate.startOf("year").format("YYYY-MM-DD HH:mm:ss"),
          endDate.endOf("year").format("YYYY-MM-DD HH:mm:ss"),
        ].join(",");
      }
      return latestTime;
    },
    isCustom() {
      return this.type === "custom";
    },
    pickerOptions({ getPickerOptions, picker, range }) {
      if (
        Object.prototype.toString.call(getPickerOptions) === "[object Function]"
      ) {
        return getPickerOptions(picker, range);
      }
      return null;
    },
    pickerDefaultTime({ range, isCustom }) {
      if (range || isCustom) {
        return ["00:00:00", "23:59:59"];
      }
      return null;
    },
    searchTimeType() {
      if (this.isCustom) {
        return this.customType;
      }
      return this.type;
    },
    realDefaultType({ searchTimeTypes, defaultType }) {
      return this.getRealDefaultType(searchTimeTypes, defaultType);
    },
    searchTimeTypeConfig() {
      if (this.defaultType !== undefined) {
        return {
          initDefault: false,
          defaultValue: this.defaultType,
        };
      }
      return {};
    },
    searchTimeTypes() {
      return this.getSearchTimeTypes();
    },
    searchTimeTypeItem() {
      return (
        this.searchTimeTypes.find((item) => item.value === this.type) ||
        this.searchTimeTypes[0]
      );
    },
    picker() {
      if (!this.searchTimeTypeItem) {
        return "date";
      }
      return this.searchTimeTypeItem.picker;
    },
    pickerType() {
      if (this.picker === "min") {
        return this.range ? "date-minselectrange" : "date-minselect";
      } else if (this.picker === "time") {
        return this.range ? "date-hourselectrange" : "date-hourselect";
      } else if (this.picker === "date") {
        return this.range ? "daterange" : "date";
      } else if (this.picker === "month") {
        return this.range ? "monthrange" : "month";
      } else if (this.picker === "year") {
        return this.range ? "yearrange" : "year";
      } else if (this.picker === "custom") {
        return this.customType === "102" ? "date-hourselectrange" : "daterange";
      }
      return "date";
    },
    datePickerSelect() {
      if (this.isCustom) {
        return "range";
      }
      return this.range ? "range" : "eq";
    },
  },
  watch: {
    type: "refreshTime",
    customType: "refreshTime",
  },
  mounted() {
    if (this.defaultTime) {
      this.latestTime = this.defaultTime;
    } else {
      this.refreshTime();
    }
  },
  methods: {
    refreshTime() {
      this.refreshing = true;
      this.resetValue();
      this.$nextTick(() => {
        this.refreshing = false;
      });
    },
    changeHandle(type) {
      if (type === "realTime") {
        this.onRealTime = false;
      } else {
        this.onRealTime = true;
      }
      this.$emit("handleChange", type);
    },
    onChange(time) {
      this.latestTime = time;
      this.resetTime = time;
    },
    onBlur() {
      const onPick = this.pickerOptions?.onPick;
      typeof onPick === "function" && onPick({});
    },
    getRealDefaultType(searchTimeTypes, defaultType) {
      const type = (defaultType && TimeTypes[defaultType]) || null;
      console.log("type", type);
      if (type) {
        return type.value;
      }
      if (searchTimeTypes.length > 0) {
        return searchTimeTypes[0].value;
      }
      return "";
    },
    getSearchTimeTypes() {
      if (this.searchTypes) {
        return this.searchTypes;
      }
      return (this.types || "date,month,year")
        .split(",")
        .map((type) => TimeTypes[type])
        .filter(Boolean);
    },
    resetValue() {
      if (this.getDefaultTime) {
        this.latestTime = this.getDefaultTime(this.picker, this.range);
        return;
      }
      if (this.picker === "min" && this.range) {
        this.resetMinRangeValue();
      } else if (this.picker === "min" && !this.range) {
        this.resetMinSingleValue();
      } else if (this.picker === "time" && this.range) {
        this.resetHourRangeValue();
      } else if (this.picker === "time" && !this.range) {
        this.resetHourSingleValue();
      } else if (this.picker === "date" && this.range) {
        this.resetDateRangeValue();
      } else if (this.picker === "date" && !this.range) {
        this.resetDateSingleValue();
      } else if (this.picker === "month" && this.range) {
        this.resetMonthRangeValue();
      } else if (this.picker === "month" && !this.range) {
        this.resetMonthSingleValue();
      } else if (this.picker === "year" && this.range) {
        this.resetYearRangeValue();
      } else if (this.picker === "year" && !this.range) {
        this.resetYearSingleValue();
      } else if (this.picker === "custom" && this.customType === "102") {
        this.resetCustomHourValue();
      } else if (this.picker === "custom" && this.customType === "103") {
        this.resetCustomDateValue();
      }
    },
    resetMinRangeValue() {
      const now = moment();
      const start = now.format("YYYY-MM-DD 00:00:00");
      const end = now.format("YYYY-MM-DD 23:59:59");
      this.latestTime = [start, end].join(",");
    },
    resetMinSingleValue() {
      const time = this.resetTime || this.defaultTime || "";
      if (time) {
        this.latestTime = time.split(",")[0];
        return;
      }
      this.latestTime = moment().format("YYYY-MM-DD HH:mm:00");
    },
    resetHourRangeValue() {
      const now = moment();
      const start = now.format("YYYY-MM-DD 00:00:00");
      const end = now.format("YYYY-MM-DD 23:59:59");
      this.latestTime = [start, end].join(",");
    },
    resetHourSingleValue() {
      const time = this.resetTime || this.defaultTime || "";
      if (time) {
        this.latestTime = time.split(",")[0];
        return;
      }
      this.latestTime = moment().format("YYYY-MM-DD HH:00:00");
    },
    resetDateRangeValue() {
      const now = moment();
      const end = now.format("YYYY-MM-DD 23:59:59");
      const start = now.subtract(1, "days").format("YYYY-MM-DD 00:00:00");
      this.latestTime = [start, end].join(",");
    },
    resetDateSingleValue() {
      const time = this.resetTime || this.defaultTime || "";
      if (time) {
        this.latestTime = time.split(",")[0];
        return;
      }
      this.latestTime = moment().format("YYYY-MM-DD 00:00:00");
    },
    resetMonthRangeValue() {
      const now = moment();
      const end = now.endOf("month").format("YYYY-MM-DD HH:mm:ss");
      const start = now.subtract(1, "months").format("YYYY-MM-01 00:00:00");
      this.latestTime = [start, end].join(",");
    },
    resetMonthSingleValue() {
      const time = this.resetTime || this.defaultTime || "";
      if (time) {
        this.latestTime = time.split(",")[0];
        return;
      }
      this.latestTime = moment().format("YYYY-MM-01 00:00:00");
    },
    resetYearRangeValue() {
      const now = moment();
      const start = now.format("YYYY-01-01 00:00:00");
      const end = now.endOf("year").format("YYYY-MM-DD HH:mm:ss");
      this.latestTime = [start, end].join(",");
    },
    resetYearSingleValue() {
      const time = this.resetTime || this.defaultTime || "";
      if (time) {
        this.latestTime = time.split(",")[0];
        return;
      }
      this.latestTime = moment().format("YYYY-01-01 00:00:00");
    },
    resetCustomHourValue() {
      this.resetHourRangeValue();
    },
    resetCustomDateValue() {
      this.resetDateRangeValue();
    },
  },
};
</script>

<style lang="less">
.ui-timerangs {
  margin-right: 10px;

  .custom-container {
    display: flex;
    flex-direction: row;
    align-items: center;
  }
}
</style>
